/**
 * Project Name:jh
 * File Name:WSServerPoint.java
 * Package Name:com.jh.web
 * Date:下午5:02:31
 * Copyright (c) 2021, LZ All Rights Reserved.
 *
*/

package com.jh.comm;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.jh.pojo.EntityT;

/**
 * Description: <br/>
 * Date: 下午5:02:31 <br/>
 * 
 * @author lz E-mail:withitren@outlook.com
 * @version
 * @see
 */
@ServerEndpoint(value = "/radar")
public class WSServerPoint {
    static final Logger logger = LoggerFactory.getLogger(WSServerPoint.class);

    // 存放用户以及对应的Session
    private static Map<Session, String> sessionUserInfo = new HashMap<Session, String>();

    // 存放前端传过来的信息，使用键值对，多个键值对之间使用&隔开
    private Map<String, String> userInfo;

    /*store sys ws client session and name ,just a pair of key-value sys-client-name & session*/
    private static Map<String, Session> sysWsClientMap = new HashMap<String, Session>();

    /*ipcam key-value sys-client-name & session*/
    private static Map<String, Session> ipcamWsClientMap = new HashMap<String, Session>();

    // json
    // private static Gson g = new Gson();
    private Gson g = new Gson();

    // 登录用户名变量
    private String loginUsername;

    // radar system websocket client name
    private static String radarWsClientName = null;

    // ipcam system websocket client name
    private static String ipcamWsClientName = null;

    private byte[] b;

    private static Set<Session> set = new HashSet<Session>();

    private static Set<Session> bsWsClientSet = new HashSet<Session>();

    private int wsSendFlag = -1;

    static {
        /*read configration from Properties*/
        Properties prop = new Properties();
        try {
            prop.load(WSServerPoint.class.getResourceAsStream("/appConfig.properties"));
            // throw new Exception("OK!");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        radarWsClientName = prop.getProperty("sysWsClientName", "sysRadarComm001");
        ipcamWsClientName = prop.getProperty("ipcamWsClientName", "sysIPCamComm002");
    }

    @OnOpen
    public void OnOpen(Session s) throws UnsupportedEncodingException { // start
        System.out.println("OnOpen！");
        String queryString = s.getQueryString();
        queryString = URLDecoder.decode(queryString, "utf-8");
        System.out.println(queryString);

        userInfo = new HashMap<String, String>();
        if (queryString.contains("&")) {
            String[] split = queryString.split("\\&");
            for (String string : split) {
                String[] split2 = string.split("=");
                userInfo.put(split2[0], split2[1]);
            }
        } else {
            String[] split = queryString.split("=");
            userInfo.put(split[0], split[1]);
        }
        System.out.println("before userList.add:" + loginUsername);
        loginUsername = userInfo.get("loginName");

        System.out.println("userInfo.get(\"loginName\")" + loginUsername);
        System.out.println(userInfo.toString());
        /* 每次连接一个websocket,就加入Map */
        sessionUserInfo.put(s, loginUsername);
        /* 每次连接一个websocket,就加入集合 */
        set.add(s);
        if (loginUsername.equals(radarWsClientName)) {
            /*system ws client radar*/
            sysWsClientMap.put(radarWsClientName, s);
            System.out.println("---->add radar sys ws client 1 :" + radarWsClientName + "  session: " + s);
            logger.debug("---->add radar sys ws client 1: + radarWsClientName" + "  session: " + s);
        } else if (loginUsername.equals(ipcamWsClientName)) {
            /*system ipcam ws client ipcam*/
            ipcamWsClientMap.put(ipcamWsClientName, s);
            System.out.println("---->add ipcam sys ws client 2: " + ipcamWsClientName + "  session: " + s);
            logger.debug("---->add ipcam sys ws client 2: " + ipcamWsClientName + "  session: " + s);
        } else {
            /*browser ws client*/
            bsWsClientSet.add(s);
            System.out.println("---->" + "add browser ws client 3: " + loginUsername + "  session: " + s);
            logger.debug("---->add browser ws client 3: " + loginUsername + "  session: " + s);
        }
        // this.broadCast(set, "from ws server info");
        // RXBQTakeThread rxbqTakeThread = new RXBQTakeThread();
        // rxbqTakeThread.start();
    }

    @OnClose
    public void OnClose(Session s) { // end
        System.out.println("OnClose！");

        if (loginUsername.equals(radarWsClientName)) {
            sysWsClientMap.remove(radarWsClientName, s);
            System.out.println("---->removed radar ws client: " + radarWsClientName);
        } else if (loginUsername.equals(ipcamWsClientName)) {
            ipcamWsClientMap.remove(ipcamWsClientName, s);
            System.out.println("---->removed ipcam ws client: " + ipcamWsClientName);
        } else {
            System.out.println("---->removed browser ws client: " + sessionUserInfo.get(s));
            bsWsClientSet.remove(s);
            // 与上一语句等效，该map里只有一对键值对
            // sysWsClientMap.clear();
        }
        set.remove(s);
        sessionUserInfo.remove(s);
    }

    @OnMessage
    public void OnMessage(String msg, Session s) { // incoming
        System.out.println("OnMessage String！");
        System.out.println("msg: " + msg);
        logger.debug("---->" + "msg: " + msg);

        EntityT entityT = g.fromJson(msg, EntityT.class);
        System.out.println(entityT.toString());
        logger.debug("---->" + entityT.toString());
        System.out.println("Type: " + entityT.getType());
        logger.debug("---->" + "Type: " + entityT.getType());
        wsSendFlag = entityT.getType();

        /*  msg direction is up to EntityT type
         * 1  - 99  : radar   ---> browser
         *100 - 199 : ipcam   ---> browser
         *200 -     : browser ---> ipcam 
         * */

        if (wsSendFlag < 200) {
            this.broadCast(bsWsClientSet, msg);
        } else {
            /* browser  to ipcam */
            Session ipcamSession = ipcamWsClientMap.get(ipcamWsClientName);
            System.out.println("ipcam session: " + ipcamSession + ",  ipcam name: " + ipcamWsClientName);
            logger.debug("ipcam session: " + ipcamSession + ",  ipcam name: " + ipcamWsClientName);
            this.sendTextToSession(ipcamSession, msg);
        }

        // this.broadCast(set, msg);
    }

    @OnMessage
    public void OnMessage(byte[] inputStream, Session s, boolean last) {
        System.out.println("OnMessage byte！");

    }

    @OnError
    public void onError(Throwable t) throws Throwable {
        System.out.println("onError！");
    }

    // 发送信息方法
    private void broadCast(Set<Session> set, String msg) {
        for (Session s : set) {
            try {
                s.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                logger.error(e.getMessage(), e);
            }
        }
    }

    // 发送信息方法
    private void sendTextToSession(Session s, String msg) {
        try {
            s.getBasicRemote().sendText(msg);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            logger.error(e.getMessage(), e);
        }
    }

}
